package com.hk.admin.common.util;

import org.apache.commons.codec.binary.Base64;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.UUID;


/**
 * <br>
 * <b>功能：</b>文件工具类<br>
 * <b>作者：</b>Pan.ShiJu<br>
 * <b>日期：</b>2017/4/11 23:27<br>
 */
public class FileUtil {

    public static final String BACKSLASH_REGEX = "\\\\";
    public static final String SLASH = "/";
    public static final String SPOT = ".";
    public static final String COMMA = ",";
    public static final String SEMICOLON = ";";

    public static final String BASE64_START_FLAG = "data:";
    public static final Integer BASE64_SPLIT_ARRAY_LENGTH = 2;

    //base64字符串转化成图片
    public static String writeImageBase64ToFile(String base64ImgData, String rootPath, String urlPrefix) {
        // 截取前面的标志，逗号分割
        String[] arr = base64ImgData.split(COMMA);
        if (arr.length != BASE64_SPLIT_ARRAY_LENGTH) {
            return null;
        }
        try {
            // UUID文件名
            String uuidFileName = getFileName();
            // 文件后缀
            String fileSuffix = SPOT + getImageSuffixByBase64(arr[0]);
            String fileName = uuidFileName + fileSuffix;
            Base64 base64 = new Base64();
            byte[] fileBytes = base64.decode(arr[1]);
            return writeSingleFileToDisk(fileBytes, fileName, rootPath, urlPrefix);
        } catch (IOException e) {
            return null;
        }
    }

    private static String getImageSuffixByBase64(String base64Str) {
        return base64Str.substring(base64Str.lastIndexOf(SLASH) + 1, base64Str.lastIndexOf(SEMICOLON));
    }

    /**
     * 文件写入磁盘
     *
     * @param file 上传的文件
     * @return 文件访问url
     */
    public static String writeSingleFileToDisk(MultipartFile file, String rootPath, String urlPrefix) {
        try {
            // UUID文件名
            String uuidFileName = getFileName();
            // 文件后缀
            String fileSuffix = getFileSuffix(file.getOriginalFilename());
            String fileName = uuidFileName + fileSuffix;
            return writeSingleFileToDisk(file.getBytes(), fileName, rootPath, urlPrefix);
        } catch (IOException e) {
            return null;
        }
    }

    public static String writeSingleFileToDisk(byte[] fileBytes, String fileName, String rootPath, String urlPrefix) throws IOException {
        // 相对路径
        String relativePath = getRelativePath(rootPath);
        // 文件存储路径
        String fullPath = rootPath + relativePath + fileName;

        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(fullPath)));
        out.write(fileBytes);
        out.flush();
        out.close();

        // 访问的url
        String fileUrl = urlPrefix + relativePath + fileName;
        // 转换url的分隔符
        fileUrl = fileUrl.replaceAll(BACKSLASH_REGEX, SLASH);
        return fileUrl;
    }

    /**
     * 文件后缀名
     *
     * @param originalFilename 原始文件名
     */
    public static String getFileSuffix(String originalFilename) {
        return originalFilename.substring(originalFilename.lastIndexOf(SPOT) + 1);
    }


    /**
     * 获取文件名称
     */
    private static String getFileName() {
        return UUID.randomUUID().toString();
    }

    /**
     * 上传文件的根目录，不存在就创建
     */
    private static String getRelativePath(String rootPath) {
        Calendar calendar = new GregorianCalendar();
        // 图片上传的相对路径
        String relativePath = File.separator +
                calendar.get(Calendar.YEAR) + File.separator +
                (calendar.get(Calendar.MONTH) + 1) + File.separator +
                calendar.get(Calendar.DAY_OF_MONTH) + File.separator;
        // 图片上传的完整路径
        String fullPath = rootPath + relativePath;
        File rootPathFile = new File(fullPath);
        if (!rootPathFile.exists() && !rootPathFile.isDirectory()) {
            if (!rootPathFile.mkdirs()) {
                return File.separator;
            }
        }
        return relativePath;
    }

}
